﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SD.LLBLGen.Pro.ORMSupportClasses;
using MyHealthOnline.Dal.Generated.EntityClasses;
using MyHealthOnline.Dal.Generated.CollectionClasses;
using MyHealthOnline.Dal.Generated.HelperClasses;

namespace MyHealthOnline.Business
{
    public class QuestionBusiness
    {

        public static void AddOpenQuestion(int consultId, string questionText, bool include)
        {
            QuestionEntity question = CreateNewQuestion("Open",questionText, include);
            CreateOpenQuestion(question);
            question.Save();
            
            AddQuestionToConsult(question, consultId);
        }

        public static void UpdateOpenQuestion(OpenQuestionEntity openQuestion, string answer)
        {
            openQuestion.Question.AnswerDate = DateTime.Now;
            openQuestion.Answer = answer;
            openQuestion.Save();
            openQuestion.Question.Save();

            ConsultBusiness.UpdateConsultStatus(openQuestion.Question.ConsultQuestion.Consult,
                                    MessageStatusEnum.WaitingForSpecialistResponse);
        }

        public static void AddMultiQuestion(int consultId, string questionText, string choices, bool include)
        {
            QuestionEntity question = CreateNewQuestion("Multi", questionText, include);
            CreateMultiQuestion(choices, question);
            question.Save();
            
            AddQuestionToConsult(question, consultId);
        }

        public static void CreateMultiQuestion(string choices, QuestionEntity question)
        {
            MultiChoiceQuestionEntity multiChoiceQuestion = new MultiChoiceQuestionEntity();
            multiChoiceQuestion.Answer = "";
            multiChoiceQuestion.PatientRemarks = "";
            multiChoiceQuestion.QuestionId = question.Id;
            multiChoiceQuestion.Question = question;
            question.MultiChoiceQuestion = multiChoiceQuestion;
            multiChoiceQuestion.Choices = choices;
            multiChoiceQuestion.Save();
        }

        public static void UpdateMultiQuestion(MultiChoiceQuestionEntity multiChoiceQuestion, string answer, string patientRemarks)
        {
            multiChoiceQuestion.Answer = answer;
            multiChoiceQuestion.PatientRemarks = patientRemarks;
            multiChoiceQuestion.Save();

            multiChoiceQuestion.Question.AnswerDate = DateTime.Now.Date;
            multiChoiceQuestion.Question.Save();

            ConsultBusiness.UpdateConsultStatus(multiChoiceQuestion.Question.ConsultQuestion.Consult,
                                MessageStatusEnum.WaitingForSpecialistResponse);
        
        }

        public static void AddDateQuestion(int consultId, string questionText, bool include)
        {
            QuestionEntity question = CreateNewQuestion("Date",questionText, include);
            CreateDateQuestion(question);
            question.Save();
            
            AddQuestionToConsult(question, consultId);
        
        }

        public static QuestionEntity CreateNewQuestion(string type, string questionText, bool isDatabaseQuestion)
        {
            QuestionEntity question = new QuestionEntity
            {
                Type = type,
                QuestionText = questionText,
                IsDatabaseQuestion = isDatabaseQuestion,
                QuestionDate=DateTime.Now,
                AnswerDate=null,
                DateAnswer=null,
                OpenAnswer="",
                MultiAnswer="",
                MultiPatientRemarks=""
            };

            question.Save();
            return question;
        }

        public static void UpdateDateQuestion(DateQuestionEntity dateQuestion, DateTime answer)
        {
            try
            {
                dateQuestion.Answer = answer;
                dateQuestion.Question.AnswerDate = DateTime.Now;

                dateQuestion.Save();
                dateQuestion.Question.Save();

                ConsultBusiness.UpdateConsultStatus(dateQuestion.Question.ConsultQuestion.Consult,
                                    MessageStatusEnum.WaitingForSpecialistResponse);
            }
            catch { }
        
        }

        public static void AddDatabaseQuestion(int consultId, int dbQuestionId)
        {
            PredicateExpression filter = new PredicateExpression(QuestionFields.Id == dbQuestionId);
            QuestionCollection questionColl = new QuestionCollection();
            questionColl.GetMulti(filter);

            if (questionColl.Count() > 0)
            {
                QuestionEntity question = new QuestionEntity();
                question = questionColl.ElementAt(0);

                QuestionEntity newQuestion = CreateNewQuestionAndRelatedQuestionType(question);

                AddQuestionToConsult(newQuestion, consultId);
            }
        }

        public static QuestionEntity CreateNewQuestionAndRelatedQuestionType(QuestionEntity question)
        {
            QuestionEntity newQuestion = CreateNewQuestion(question);

            if (question.Type == "Open" && question.OpenQuestion != null)
            {
                CreateOpenQuestion(newQuestion);
            }
            else if (question.Type == "Multi" && question.Type == "Multi")
            {
                CreateMultiQuestion(question.MultiChoiceQuestion.Choices, newQuestion);
            }
            else if (question.Type == "Date" && question.Type == "Date")
            {
                CreateDateQuestion(newQuestion);
            }

            newQuestion.Save();

            return newQuestion;
        }

        public static QuestionEntity CreateNewQuestion(QuestionEntity question)
        {
            QuestionEntity newQuestion=CreateNewQuestion (question.Type,question.QuestionText,false);
            return newQuestion;
        }

        public static DateQuestionEntity CreateDateQuestion(QuestionEntity newQuestion)
        {
            DateQuestionEntity dateQuestion = new DateQuestionEntity();
            dateQuestion.Answer = null;
            dateQuestion.Question = newQuestion;
            newQuestion.DateQuestion = dateQuestion;
            dateQuestion.QuestionId = newQuestion.Id;
            dateQuestion.Save();

            return dateQuestion;
        }

        public static void CreateOpenQuestion(QuestionEntity newQuestion)
        {
            OpenQuestionEntity openQuestion = new OpenQuestionEntity();
            openQuestion.Answer = "";
            openQuestion.Question = newQuestion;
            newQuestion.OpenQuestion = openQuestion;
            openQuestion.QuestionId = newQuestion.Id;
            openQuestion.Save();
        }

        public static bool AddQuestionToConsult(QuestionEntity question, int consultId)
        {
            try
            {
                PredicateExpression filter = new PredicateExpression(ConsultFields.Id == consultId);
                ConsultCollection consultColl = new ConsultCollection();
                consultColl.GetMulti(filter);
                if (consultColl.Count() > 0)
                {
                    ConsultEntity consult = consultColl.ElementAt(0);

                    ConsultQuestionEntity consultQuestion = new ConsultQuestionEntity();
                    consultQuestion.ConsultId = consultId;
                    consultQuestion.Consult = consult;
                    consultQuestion.QuestionId = question.Id;
                    consultQuestion.Question = question;
                    consultQuestion.Save();

                    consult.ConsultQuestion.Add(consultQuestion);
                    consult.Save();
                    ConsultBusiness.UpdateConsultStatus(consult,
                                    MessageStatusEnum.WaitingForPatientReaction);
                }
                return true;

            }
            catch
            {
                return false;
            }
        }

        public static QuestionCollection GetQuestionsFromDatabase()
        {
            try
            {
                PredicateExpression filter = new PredicateExpression(QuestionFields.IsDatabaseQuestion == true);
                QuestionCollection questionList = new QuestionCollection();
                questionList.GetMulti(filter);

                return questionList;
            }
            catch
            {
                return null;
            }
        }

        public static QuestionCollection GetQuestionsByConsult(int consultId)
        {
            PredicateExpression filter = new PredicateExpression(ConsultQuestionFields.ConsultId == consultId);
            RelationCollection relColl = new RelationCollection();
            relColl.Add(QuestionEntity.Relations.ConsultQuestionEntityUsingQuestionId).CustomFilter = filter;
            
            QuestionCollection questionColl = new QuestionCollection();
            questionColl.GetMulti(null,relColl);

            return questionColl;
        }

        public static QuestionCollection GetAnsweredQuestionsByConsult(int consultId)
        {
            PredicateExpression filter = new PredicateExpression();
            filter.Add(new FieldCompareNullPredicate(QuestionFields.AnswerDate,true));
            QuestionCollection questionColl = GetQuestionsByConsult(consultId);
            questionColl.GetMulti(filter);
            return questionColl;
        }

        public static QuestionCollection GetUnansweredQuestionsByConsult(int consultId)
        {
            PredicateExpression filter=new PredicateExpression();
            filter.Add(new FieldCompareNullPredicate(QuestionFields.AnswerDate));
            QuestionCollection questionColl = GetQuestionsByConsult(consultId);
            questionColl.GetMulti(filter);
            return questionColl;
        }

        public static QuestionCollection GetQuestionnaireQuestions(int questionnaireId)
        {
            PredicateExpression filter = new PredicateExpression(QuestionnaireFields.Id == questionnaireId);
            RelationCollection relColl = new RelationCollection();
            relColl.Add(QuestionEntity.Relations.QuestionnaireQuestionEntityUsingQuestionId);
            relColl.Add(QuestionnaireQuestionEntity.Relations.QuestionnaireEntityUsingQuestionnaireId).CustomFilter=filter;

            QuestionCollection questionColl = new QuestionCollection();
            questionColl.GetMulti(null,relColl);

            return questionColl;

        }
    }
}
